home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / gnome-games-data / glchess / scene / opengl / texture.py < prev   
Encoding:
Python Source  |  2009-04-14  |  4.7 KB  |  156 lines

  1. # -*- coding: utf-8 -*-
  2. from OpenGL.GL import *
  3. from OpenGL.GLU import *
  4. import png
  5. import array
  6.  
  7. class Texture:
  8.     """
  9.     """
  10.     # Texture data
  11.     __data   = None
  12.     __format = GL_RGB
  13.     __width  = None
  14.     __height = None
  15.     
  16.     # Material properties
  17.     __ambient   = None
  18.     __diffuse   = None
  19.     __specular  = None
  20.     __emission  = None
  21.     __shininess = None
  22.  
  23.     # OpenGL texture ID
  24.     __texture = None
  25.     
  26.     def __init__(self, fileName,
  27.                  ambient  = (0.2, 0.2, 0.2, 1.0),
  28.                  diffuse  = (0.8, 0.8, 0.8, 1.0),
  29.                  specular = (0.0, 0.0, 0.0, 1.0),
  30.                  emission = (0.0, 0.0, 0.0, 1.0),
  31.                  shininess = 0.0):
  32.         """Constructor for an openGL texture.
  33.         
  34.         'fileName' is the name of the image file to use for the texture (string).
  35.         
  36.         An IOError is raised if the file does not exist.
  37.         This does not need an openGL context.
  38.         """
  39.         self.__ambient = ambient
  40.         self.__diffuse = diffuse
  41.         self.__specular = specular
  42.         self.__emission = emission
  43.         self.__shininess = shininess
  44.         try:
  45.             self.__loadPIL(fileName)
  46.         except ImportError:
  47.             self.__loadPNG(fileName)
  48.  
  49.     def __loadPNG(self, fileName):
  50.         """
  51.         """
  52.         try:
  53.             reader = png.Reader(fileName)
  54.         except IOError, e:
  55.             print 'Error loading texture file: %s: %s' % (fileName, e.strerror)
  56.             self.__data = None
  57.             return
  58.  
  59.         try:
  60.             (width, height, data, metaData) = reader.read()
  61.         except png.Error, e:
  62.             print 'Error parsing PNG file %s: %s' % (fileName, e.message)
  63.             self.__data = None
  64.             return
  65.         
  66.         self.__width = width
  67.         self.__height = height
  68.         self.__data = array.array('B', data).tostring()
  69.  
  70.         if metaData['has_alpha']:
  71.             self.__format = GL_RGBA
  72.         else:
  73.             self.__format = GL_RGB
  74.  
  75.     def __loadPIL(self, fileName):
  76.         """
  77.         """
  78.         import Image
  79.         
  80.         # Load the image file
  81.         try:
  82.             image = Image.open(fileName)
  83.         except IOError, e:
  84.             print 'Error loading texture file: %s: %s' % (fileName, e.strerror)
  85.             self.__data = None
  86.             return            
  87.  
  88.         # Crop the image so it has height/width a multiple of 2
  89.         width = image.size[0]
  90.         height = image.size[1]
  91.         w = 1
  92.         while 2*w <= width:
  93.             w *= 2
  94.         h = 1
  95.         while 2*h <= height:
  96.             h *= 2
  97.         (self.__width, self.__height) = (w, h)
  98.         image = image.crop((0, 0, w, h))
  99.  
  100.         # Convert to a format that OpenGL can access
  101.         self.__data = image.tostring('raw', 'RGB', 0, -1)
  102.         self.__format = GL_RGB
  103.  
  104.     def __generate(self):
  105.         """
  106.         """
  107.         # Return null texture if failed to load data
  108.         if self.__data is None:
  109.             return 0
  110.         
  111.         # FIXME: Can fail
  112.         texture = glGenTextures(1)
  113.             
  114.         glBindTexture(GL_TEXTURE_2D, texture)
  115.  
  116.         glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
  117.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  118.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  119.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  120.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  121.  
  122.         # Generate mipmaps
  123.         try:
  124.             gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE, self.__width, self.__height, self.__format, GL_UNSIGNED_BYTE, self.__data)
  125.         except GLUerror, e:
  126.             glTexImage2D(GL_TEXTURE_2D,
  127.                          0,                # Level
  128.                          3,                # Depth
  129.                          self.__width,     # Width
  130.                          self.__height,    # Height
  131.                          0,                # Border
  132.                          self.__format,    # Format
  133.                          GL_UNSIGNED_BYTE, # Type
  134.                          self.__data)
  135.         
  136.         return texture
  137.     
  138.     def bind(self):
  139.         """Bind this texture to the current surface.
  140.         
  141.         This requires an openGL context.
  142.         """
  143.         if self.__texture is None:
  144.             self.__texture = self.__generate()
  145.             self.__data = None
  146.  
  147.         # Use texture
  148.         glBindTexture(GL_TEXTURE_2D, self.__texture)
  149.         
  150.         # Use material properties
  151.         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, self.__ambient)
  152.         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, self.__diffuse)
  153.         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, self.__specular)
  154.         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, self.__emission)
  155.         glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, self.__shininess)
  156.